﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using RestSharp;

namespace Ymatou.ServiceCenter
{
    /// <summary>
    /// Response返回结果包装类
    /// </summary>
    /// <typeparam name="T">Response类型</typeparam>
    public class Result<T>
    {
        /// <summary>
        /// 状态码
        /// </summary>
        public int StatusCode { get; set; }

        /// <summary>
        /// 状态信息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 附加信息
        /// </summary>
        public Dictionary<string, string> Attachments { get; set; }

        /// <summary>
        /// 请求编号
        /// </summary>
        public string RequestId { get; set; }

        /// <summary>
        /// 响应值
        /// </summary>
        public T Response { get; set; }
    }

    /// <summary>
    /// 请求包数据校验接口
    /// </summary>
    public interface IValidate
    {
        /// <summary>
        /// 在发送请求前调用
        /// </summary>
        void Validate();
    }

    /// <summary>
    /// 请求资源特性接口(为了方便老的交易站点的Request类快速改造)
    /// </summary>
    public interface IResource
    {
        /// <summary>
        /// 请求资源特性
        /// </summary>
        ResourceAttribute GetResourceAttribute();
    }

    /// <summary>
    /// 默认的请求包
    /// </summary>
    public class DefaultRequest
    {
        /// <summary>
        /// 构建默认的请求包
        /// </summary>
        public DefaultRequest()
        {
            
        }

        /// <summary>
        /// 构建默认的请求包
        /// </summary>
        /// <param name="appId">应用编号</param>
        /// <param name="apiName">接口名称</param>
        /// <param name="httpMethod">http方法</param>
        /// <param name="parameterBuildType">http请求参数构建类型</param>
        public DefaultRequest(string appId, string apiName, Method httpMethod, ParameterBuildType parameterBuildType)
        {
            if(string.IsNullOrWhiteSpace(appId))
                throw new ArgumentNullException(appId);
            if(string.IsNullOrWhiteSpace(apiName))
                throw new ArgumentNullException(apiName);
            ResourceAttribute attribute = new ResourceAttribute
            {
                AppId = appId,
                ApiName = apiName,
                HttpMethod = httpMethod,
                ParameterBuildType = parameterBuildType
            };
            this.ResourceAttribute = attribute;
            this.RestRequest = this.ResourceAttribute.ParameterBuildType== ParameterBuildType.Json ? new JsonRequest() : new RestRequest();
            this.ServiceMetadata = ServiceMetadataManager.GetServiceMetadata(appId,apiName,httpMethod);
        }
        internal ResourceAttribute ResourceAttribute { get; set; }

        internal RestRequest RestRequest { get; set; }

        internal ServiceMetadata ServiceMetadata { get; set; }
        /// <summary>
        /// 添加请求参数
        /// </summary>
        /// <param name="name">参数名</param>
        /// <param name="value">参数值</param>
        public void AddParameter(string name, object value)
        {
            string apiName = ServiceMetadata != null ? ServiceMetadata.ApiPath : this.ResourceAttribute.ApiName;
            switch (this.ResourceAttribute.ParameterBuildType)
            {
                case ParameterBuildType.UrlQueryString:
                    if (apiName.Contains("{") && apiName.Contains("}"))
                        this.RestRequest.AddUrlSegment(name,value==null?"":value.ToString());
                    else
                        this.RestRequest.AddQueryParameter(name, value == null ? "" : value.ToString());
                    break;
                case ParameterBuildType.FormUrlEncoded:
                    this.RestRequest.AddParameter(name, value == null ? "" : value.ToString());
                    break;
                case ParameterBuildType.QueryOrForm:
                    if (apiName.Contains("{") && apiName.Contains("}"))
                        this.RestRequest.AddUrlSegment(name, value == null ? "" : value.ToString());
                    else
                        this.RestRequest.AddParameter(name, value == null ? "" : value.ToString());
                    break;
            }
        }

        /// <summary>
        /// 添加请求参数
        /// </summary>
        /// <param name="name">参数名</param>
        /// <param name="value">参数值</param>
        /// <param name="type">参数类型</param>
        public void AddParameter(string name, object value, ParameterType type)
        {
            this.RestRequest.AddParameter(name, value, type);
        }

        /// <summary>
        /// 添加请求参数
        /// </summary>
        /// <param name="obj">参数对象</param>
        public void AddParameter(object obj)
        {
            this.RestRequest.AddJsonBody(obj);
        }

        /// <summary>
        /// 添加文件参数
        /// </summary>
        /// <param name="name"></param>
        /// <param name="bytes"></param>
        /// <param name="fileName"></param>
        /// <param name="contentType"></param>
        public void AddFile(string name, byte[] bytes, string fileName, string contentType = null)
        {
            this.RestRequest.AddFile(name, bytes, fileName, contentType);
        }
    }
}
